﻿using log4net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DotNetMVC.OA.Common
{
    public delegate void WriteLogDel(string str);
    public class LogHelper
    {
        #region 观察者模式_多播委托
        //public static Queue<string> ExceptionStringQueue = new Queue<string>();

        //public static WriteLogDel WriteLogDelFunc;

        //public static void WriteLogToFile(string txt)
        //{
        //}

        //public static void WriteLogToSql(string txt)
        //{
        //}

        //static LogHelper()
        //{
        //    ThreadPool.QueueUserWorkItem(o =>
        //    {
        //        lock (ExceptionStringQueue)
        //        {
        //            string str = ExceptionStringQueue.Dequeue();
        //            //把异常写入日志
        //            WriteLogDelFunc = new WriteLogDel(WriteLogToFile);
        //            WriteLogDelFunc += WriteLogToSql;
        //        }
        //    });
        //}

        //public static void WriteLog(string exceptionText)
        //{
        //    lock (ExceptionStringQueue)
        //    {
        //        //异常加入队列
        //        ExceptionStringQueue.Enqueue(exceptionText);
        //    }
        //}
        #endregion

        #region 观察者模式_接口实现 + List<T>
        public static Queue<string> ExceptionStringQueue = new Queue<string>();
        public static List<ILogWriter> LogWriterList = new List<ILogWriter>();
        static LogHelper()
        {
            //LogWriterList.Add(new FileLogWriter());
            //LogWriterList.Add(new SqlLogWriter());
            LogWriterList.Add(new Log4NetWriter());

            ThreadPool.QueueUserWorkItem(o =>
            {
                while (true)
                {
                    lock (ExceptionStringQueue)
                    {
                        if (ExceptionStringQueue.Count > 0)
                        {
                            string str = ExceptionStringQueue.Dequeue();
                            //把异常写入日志
                            foreach (ILogWriter logWriter in LogWriterList)
                            {
                                logWriter.WriteLogInfo(str);
                            }
                        }
                        else
                        {
                            Thread.Sleep(30);
                        }
                    }
                }
            });
        }

        public static void WriteLog(string exceptionText)
        {
            lock (ExceptionStringQueue)
            {
                //异常加入队列
                ExceptionStringQueue.Enqueue(exceptionText);
            }
        }
        #endregion

    }

    #region 观察者模式接口实现代码
    public interface ILogWriter
    {
        void WriteLogInfo(string txt);
    }
    public class FileLogWriter : ILogWriter
    {
        public void WriteLogInfo(string txt)
        {
            //using (Stream outStream = new FileStream(@"H:\DotNetMVC.OA\DotNetMVC.OA.UI.Portal\App_Data\2018.txt", FileMode.OpenOrCreate))
            //using (StreamWriter sw = new StreamWriter(outStream, Encoding.Default))
            //{
            //    sw.WriteLine(txt);
            //}
        }
    }

    public class SqlLogWriter : ILogWriter
    {
        public void WriteLogInfo(string txt)
        {

        }
    }

    public class Log4NetWriter : ILogWriter
    {
        public void WriteLogInfo(string txt)
        {
            ILog logWriete = log4net.LogManager.GetLogger("DotNetMVC.OA");
            logWriete.Error(txt);
        }
    }
    #endregion
}
